import { AudioClip, CCFloat, Component, Enum, EventHandler, EventTouch, Intersection2D, Node, PolygonCollider2D, tween, UITransform, v3, Vec2, Vec3, _decorator } from "cc";
import { App } from "../../App";

/**
 * 如果异性精灵有叠加的情况，需要添加PolygonCollider组件，并且勾勒出精灵的轮廓
 */
enum EffectType{
    String,
    Clip,
}
const { menu, ccclass, property, disallowMultiple } = _decorator;
@ccclass
@disallowMultiple
@menu("自定义插件/控件点击音效")
export default class TouchNode extends Component {
    @property({displayName:'是否可点击', tooltip: 'i18n:COMPONENT.button.interactable'})
    interactable: boolean = true;
    @property({type:Enum(EffectType),displayName:'点击音效',tooltip:"String 填写音频文件路径\n Clip 拖放音频文件"})
    select:EffectType = EffectType.String;
    @property({displayName:'音效文件名',tooltip: '点击播放音效',visible(){return this.select === EffectType.String}})
    audioFile: string = 'click';
    @property({displayName:'音效文件', type: AudioClip, tooltip: 'AudioClip文件',visible(){return this.select === EffectType.Clip} })
    audioClip: AudioClip = null;
    @property({ type: Node,displayName:'隐藏节点', tooltip: '将从从父节点移除' })
    hideNode: Node = null;
    @property({type:CCFloat,displayName:'点击缩放比例'})
    zoomScale: number = 1.1;
    @property({ range: [0, 10],displayName:'效果持续时间'})
    duration: number = 0.1;
    @property({ type: EventHandler, tooltip: '点击响应事件' })
    clickEvent: EventHandler = null;


    private _scale: Vec3 = v3(1,1,0);
    private _pressed: boolean = false;
    private _touchPoints: Vec2[] = [];
    private _isNeedCollider: boolean = false;
    private _isCanTouch:boolean = true;
    private _isCancel:boolean = false;

    start() {
        this._scale = this.node.scale;
        this.node.on(UITransform.EventType.TOUCH_START, this.onTouchStart, this);
        this.node.on(UITransform.EventType.TOUCH_END, this.onTouchEnd, this);
        this.node.on(UITransform.EventType.TOUCH_CANCEL, this.onTouchCancel, this);
        if (this.node.getComponent(PolygonCollider2D)) {
            this._isNeedCollider = true;
            let _pos: Vec2[] = this.node.getComponent(PolygonCollider2D).points;
            const ui:UITransform = this.getComponent(UITransform) || this.addComponent(UITransform);
            for (let i = 0; i < _pos.length; ++i) {
                //this._touchPoints[i] = _pos[i].add(ui.convertToWorldSpaceAR(Vec2.ZERO_R)).mul(this._scale);
            }
        }
        if (!this.audioClip){
            App.Asset.load(this.audioFile,(clip:AudioClip)=>{
                this.audioClip = clip;
            },AudioClip);
        }
    }

    onDestroy() {
        this.node.off(UITransform.EventType.TOUCH_START, this.onTouchStart, this);
        this.node.off(UITransform.EventType.TOUCH_END, this.onTouchEnd, this);
        this.node.off(UITransform.EventType.TOUCH_CANCEL, this.onTouchCancel, this);
    };

    public bindEvent(target:Node,component:string,callFun:string,userData?:string){
        if (!App.isValid(target) || App.isEmpty(component) || App.isEmpty(callFun) || !this.interactable){
            return ;
        }
        
        const clickEvent = new EventHandler();
        clickEvent.target = target; // 这个 node 节点是你的事件处理代码组件所属的节点
        clickEvent.component = component;// 这个是代码文件名
        clickEvent.handler = callFun;
        clickEvent.customEventData = userData;
        this.clickEvent = clickEvent;
    }

    private onTouchStart(touch: EventTouch) {
        if (!this._pressed && this.interactable && this._isCanTouch) {
            this._isCanTouch = false;
            if (this._isNeedCollider) {
                if (Intersection2D.pointInPolygon(touch.getLocation(), this._touchPoints)) {
                    // @ts-ignore
                    this.node._touchListener.setSwallowTouches(true);
                    this._pressed = true;
                } else {
                    // @ts-ignore
                    this.node._touchListener.setSwallowTouches(false);
                    this._pressed = false;
                }
            } else this._pressed = true;

            if (this._pressed){
                tween(this.node).stop();
                tween(this.node).to(this.duration,{scale:v3(this.zoomScale,this.zoomScale,0)})
                .call(()=>{
                    this.audioClip && App.Audio.play(this.audioClip);
                }).start();
            }
        }
    };

    private onTouchEnd(touch: EventTouch) {
        if (this.node !== touch.target || !this._pressed || !this.interactable) return ;

        tween(this.node).stop();
        tween(this.node).to(this.duration,{scale:this._scale})
        .call(()=>{
            if (!this._isCancel){
                this.clickEvent && EventHandler.emitEvents([this.clickEvent], touch);
                this.hideNode && App.closeView(this.hideNode);
            }
        }).call(()=>{
            this._pressed = false;
            this._isCancel = false;
            this._isCanTouch = true;
        }).start();
    }
    private onTouchCancel(touch: EventTouch) {
        this._isCancel = true;
        this.onTouchEnd(touch);
    }
}
